﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;//
using Xbim.Ifc;
using Xbim.ModelGeometry.Scene;//
using Xbim.Common.Step21;
using Xbim.Common;
using Xbim.Ifc4.Kernel;
using Xbim.Ifc4.SharedBldgElements;
using Xbim.Ifc4.PropertyResource;
using Xbim.Ifc4.MeasureResource;
using Xbim.Ifc4.Interfaces;
using Newtonsoft.Json;
using Xbim.Ifc4.ElectricalDomain;
using Xbim.Ifc4.ProfileResource;
using Xbim.Ifc4.GeometryResource;
using Xbim.Ifc4.GeometricModelResource;
using Xbim.Ifc4.RepresentationResource;
using Xbim.Ifc4.GeometricConstraintResource;
using Xbim.Ifc4.MaterialResource;
using Xbim.Ifc4.ProductExtension;
using Xbim.Ifc4.PresentationOrganizationResource;
using Xbim.Ifc4.QuantityResource;
using Xbim.Ifc4.ActorResource;
using Xbim.Ifc4.DateTimeResource;
using Xbim.Ifc4.ExternalReferenceResource;
using Xbim.Ifc4.SharedBldgServiceElements;
//using Xbim.Ifc2x3.ProductExtension;
//using Xbim.Ifc2x3.Interfaces;

namespace xBimServer.Controllers
{
    public class BimIfcController : Controller
    {
        public ActionResult ToWexBim(string wFileName)
        {
            string fileName = Server.MapPath(@"\res\ifc\Ghasem.ifc");
            if (!string.IsNullOrEmpty(wFileName))
            {
                fileName = Server.MapPath(wFileName);
            }
            using (var model = IfcStore.Open(fileName))
            {
                var context = new Xbim3DModelContext(model);
                context.CreateContext();

                var wexBimFilename = Path.ChangeExtension(fileName, "wexBIM");
                using (var wexBiMfile = System.IO.File.Create(wexBimFilename))
                {
                    using (var wexBimBinaryWriter = new BinaryWriter(wexBiMfile))
                    {
                        model.SaveAsWexBim(wexBimBinaryWriter);
                        wexBimBinaryWriter.Close();
                    }
                    wexBiMfile.Close();
                }
                return Json(wexBimFilename, JsonRequestBehavior.AllowGet);
            }

        }
        // GET: /BimIfc/Index
        // 
        public ActionResult Index(string wFileName)
        {
            string fileName = Server.MapPath(@"\res\ifc\Ghasem.ifc");
            if (!string.IsNullOrEmpty(wFileName))
            {
                fileName = Server.MapPath(wFileName);
            }

            var lsInfo = new List<NodeInfo>();
            #region  
            using (var model = IfcStore.Open(fileName))
            {
                #region



                #endregion
            }
            #endregion
            return Content(JsonConvert.SerializeObject(lsInfo), "application/json");
            //return Json(lsInfo, JsonRequestBehavior.AllowGet);
        }

        // GET: /BimIfc/GetAllStoreys
        // 
        public ActionResult GetAllStoreys(string wFileName)
        {
            string fileName = Server.MapPath(@"\res\ifc\Ghasem.ifc");
            if (!string.IsNullOrEmpty(wFileName))
            {
                fileName = Server.MapPath(wFileName);
            }

            var lsInfo = new List<NodeInfo>();
            #region  
            using (var model = IfcStore.Open(fileName))
            {
                #region
                // 项目
                var prj = model.Instances.OfType<IIfcProject>().FirstOrDefault();
                if (prj != null)
                {
                    var nodeInfo = new NodeInfo { ID = prj.EntityLabel.ToString(), GlobalID = prj.GlobalId, TypeName = "项目", Name = prj.Name, Desc = prj.Description?.Value?.ToString() };
                    var properties = prj.IsDefinedBy
                      .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                      .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                      .OfType<IIfcPropertySingleValue>();
                    foreach (var prop in properties)
                    {
                        nodeInfo.LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                    }
                    lsInfo.Add(nodeInfo);
                }

                // 场地
                var allSites = model.Instances.OfType<IIfcSite>().ToList();//  model.Instances.Where<IIfcSite>(d => d.IsTypedBy.Any()).ToList();
                allSites.ForEach(item =>
                {
                    var nodeInfo = new NodeInfo { PID = prj.EntityLabel.ToString(), ID = item.EntityLabel.ToString(), GlobalID = item.GlobalId, TypeName = "场地", Name = item.Name, Desc = item.SiteAddress?.Town?.ToString() };
                    var properties = item.IsDefinedBy
                      .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                      .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                      .OfType<IIfcPropertySingleValue>();
                    foreach (var prop in properties)
                    {
                        nodeInfo.LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                    }
                    lsInfo.Add(nodeInfo);
                });
                // 建筑物
                var allBuilding = model.Instances.OfType<IIfcBuilding>().ToList();//  model.Instances.Where<IIfcBuilding>(d => d.IsTypedBy.Any()).ToList();
                allBuilding.ForEach(item =>
                {
                    var nodeInfo = new NodeInfo { PID = prj.EntityLabel.ToString(), ID = item.EntityLabel.ToString(), GlobalID = item.GlobalId, TypeName = "建筑物", Name = item.Name, Desc = item.Description?.Value?.ToString() };
                    var properties = item.IsDefinedBy
                      .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                      .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                      .OfType<IIfcPropertySingleValue>();
                    foreach (var prop in properties)
                    {
                        nodeInfo.LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                    }
                    lsInfo.Add(nodeInfo);
                });
                // 建筑物楼层
                var allBuildingStorey = model.Instances.OfType<IIfcBuildingStorey>().ToList();//  model.Instances.Where<IfcBuildingStorey>(d => d.IsTypedBy.Any()).ToList();
                allBuildingStorey.ForEach(item =>
                {
                    var nodeInfo = new NodeInfo { PID = prj.EntityLabel.ToString(), ID = item.EntityLabel.ToString(), GlobalID = item.GlobalId, TypeName = "建筑物楼层", Name = item.Name, Desc = item.Description?.Value?.ToString() };
                    var properties = item.IsDefinedBy
                      .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                      .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                      .OfType<IIfcPropertySingleValue>();
                    foreach (var prop in properties)
                    {
                        nodeInfo.LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                    }
                    lsInfo.Add(nodeInfo);
                });
                #endregion
            }
            #endregion
            return Content(JsonConvert.SerializeObject(lsInfo), "application/json");
            //return Json(lsInfo, JsonRequestBehavior.AllowGet);
        }
        // GET: /BimIfc/GetDomains
        // 
        public ActionResult GetDomains(string wFileName)
        {
            string fileName = Server.MapPath(@"\res\ifc\Ghasem.ifc");
            if (!string.IsNullOrEmpty(wFileName))
            {
                fileName = Server.MapPath(wFileName);
            }

            var lsInfo = new List<NodeInfo>();
            #region  
            using (var model = IfcStore.Open(fileName))
            {
                #region
                // 电气  IIfcElectricalElement
                var allSites = model.Instances.OfType<IIfcElectricAppliance>().ToList();//  model.Instances.Where<IIfcSite>(d => d.IsTypedBy.Any()).ToList();
                allSites.ForEach(item =>
                {
                    var nodeInfo = new NodeInfo { ID = item.EntityLabel.ToString(), GlobalID = item.GlobalId, TypeName = "电气", Name = item.Name, Desc = item.Description?.Value.ToString() };

                    var properties = item.IsDefinedBy 
                    .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet) 
                    .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                    .OfType<IIfcPropertySingleValue>();
                    foreach (var prop in properties)
                    {
                        nodeInfo.LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                    }
                    //var properties = item.IsDefinedBy
                    // .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                    // .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                    // .OfType<IIfcPropertySingleValue>();
                    //foreach (var prop in properties)
                    //{
                    //    nodeInfo.LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                    //}
                    lsInfo.Add(nodeInfo);
                });

                #endregion
            }
            #endregion
            return Content(JsonConvert.SerializeObject(lsInfo), "application/json");
            //return Json(lsInfo, JsonRequestBehavior.AllowGet);
        }
        // GET: /BimIfc/GetEntityProperties
        // 
        public ActionResult GetEntityProperties(string wFileName, int id)
        {
            string fileName = Server.MapPath(@"\res\ifc\Ghasem.ifc");
            if (!string.IsNullOrEmpty(wFileName))
            {
                fileName = Server.MapPath(wFileName);
            }

            var LsPropertie = new List<NodePropertieInfo>();
            #region  
            using (var model = IfcStore.Open(fileName))
            {
                // var entity = model.Instances.OfType<IIfcBuildingElement>().Where(x => x.EntityLabel == id).FirstOrDefault();                 
                //if (entity!=null)
                //{
                //    var properties = entity.IsDefinedBy
                //      .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                //      .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                //      .OfType<IIfcPropertySingleValue>();
                //    foreach (var prop in properties)
                //    {
                //        LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                //    }
                //}

                var entity = model.Instances.OfType<IIfcElement>().Where(x => x.EntityLabel == id).FirstOrDefault();
                if (entity != null)
                {
                    var properties = entity.IsDefinedBy
                      .Where(r => r.RelatingPropertyDefinition is IIfcPropertySet)
                      .SelectMany(r => ((IIfcPropertySet)r.RelatingPropertyDefinition).HasProperties)
                      .OfType<IIfcPropertySingleValue>();
                    foreach (var prop in properties)
                    {
                        LsPropertie.Add(new NodePropertieInfo { Name = prop.Name, Value = prop.NominalValue.ToString() });
                    }
                }

            }
            #endregion
            return Content(JsonConvert.SerializeObject(LsPropertie), "application/json");
            //return Json(lsInfo, JsonRequestBehavior.AllowGet);
        }


    }


    public class NodeInfo
    {
        [JsonProperty("pid")]
        public string PID { get; set; }

        public string PName { get; set; }
        [JsonProperty("id")]
        public string ID { get; set; }
        public string GlobalID { get; set; }
        public string TypeName { get; set; }
        [JsonProperty("text")]
        public string Name { get; set; }
        public string Value { get; set; }
        public string Desc { get; set; }

        public List<NodePropertieInfo> LsPropertie { get; set; }

        public NodeInfo()
        {
            PID = "0";
            LsPropertie = new List<NodePropertieInfo>();
        }
    }
    public class NodePropertieInfo
    {
        public string TypeName { get; set; }
        public string Name { get; set; }
        public string Value { get; set; }
        public string Desc { get; set; }

    }

}